From e7570f0014f69881e8196a78b0827ce5209b7215 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 9 Nov 2005 14:53:12 +0100 Subject: [PATCH] Support recent change moving virtual IOAPIC model into Xen for ia64/VTI. Now ia64/vti will create links to arch/x86/dm/vmx_vioapic.c and include/x86/vmx_vlapic.h. Firstly, a small change to common virtual IOAPIC model to be used by both sides. Also some compilation fix to tools is included in first one. Secondly, there are ia64-specific changes to hook to common IOAPIC model. Based on this patch upon latest xen-ia64-unstable tip, we can see multiple domains working again on XEN/IA64, including both domU and VTI domain simultaneously in run-time. Signed-off-by Kevin Tian Signed-off-by Anthony Xu Signed-off-by Yunhong Jiang Signed-off-by Eddie Dong --- tools/examples/xmexample.vti | 3 + tools/ioemu/ia64_intrinsic.h | 1 + tools/ioemu/target-i386-dm/Makefile | 2 +- tools/ioemu/vl.c | 4 +- tools/libxc/xc_ia64_stubs.c | 1 + tools/libxc/xc_linux_build.c | 2 +- xen/arch/ia64/Makefile | 7 ++- xen/arch/ia64/Rules.mk | 2 +- xen/arch/ia64/vmx/mmio.c | 7 +++ xen/arch/ia64/vmx/vlsapic.c | 98 +++++++++++++++++------------ xen/arch/ia64/vmx/vmx_init.c | 36 +++++------ xen/arch/ia64/vmx/vmx_support.c | 5 +- xen/arch/ia64/xen/domain.c | 9 ++- xen/arch/x86/dm/vmx_vioapic.c | 6 +- xen/include/asm-ia64/vmx.h | 23 ++++++- xen/include/asm-ia64/vmx_platform.h | 48 ++++++++++++-- xen/include/asm-ia64/vmx_vcpu.h | 7 --- xen/include/asm-ia64/vmx_vpd.h | 5 +- xen/include/asm-x86/vmx_vioapic.h | 25 ++------ xen/include/asm-x86/vmx_vlapic.h | 3 + 20 files changed, 181 insertions(+), 113 deletions(-) diff --git a/tools/examples/xmexample.vti b/tools/examples/xmexample.vti index 63bdc25d3a..540543a991 100644 --- a/tools/examples/xmexample.vti +++ b/tools/examples/xmexample.vti @@ -26,6 +26,9 @@ name = "ExampleVMXDomain" # Which CPU to start domain on? #cpu = -1 # leave to Xen to pick +# Disable vif for now +nics=0 + # Optionally define mac and/or bridge for the network interfaces. # Random MACs are assigned if not given. #vif = [ 'mac=aa:00:00:00:00:11, bridge=xen-br0' ] diff --git a/tools/ioemu/ia64_intrinsic.h b/tools/ioemu/ia64_intrinsic.h index c0d637ff85..07ea6be0f8 100644 --- a/tools/ioemu/ia64_intrinsic.h +++ b/tools/ioemu/ia64_intrinsic.h @@ -236,6 +236,7 @@ u64_t _InterlockedCompareExchange64_acq(volatile uint64_t *dest, uint64_t xchg, #define __ia64_fc(addr) asm volatile ("fc %0" :: "r"(addr) : "memory") #define ia64_sync_i() asm volatile (";; sync.i" ::: "memory") +register unsigned long ia64_r13 asm ("r13") __attribute_used__; #define __ia64_getreg(regnum) \ ({ \ uint64_t ia64_intri_res; \ diff --git a/tools/ioemu/target-i386-dm/Makefile b/tools/ioemu/target-i386-dm/Makefile index c05013f75c..ba4926bfa7 100644 --- a/tools/ioemu/target-i386-dm/Makefile +++ b/tools/ioemu/target-i386-dm/Makefile @@ -188,7 +188,7 @@ endif ######################################################### DEFINES+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -LIBS+=-lm -L../../libxc -lxenctrl +LIBS+=-lm -L../../libxc -lxenctrl -lxenguest ifndef CONFIG_USER_ONLY LIBS+=-lz endif diff --git a/tools/ioemu/vl.c b/tools/ioemu/vl.c index 3ea7828412..294e3bcdc7 100644 --- a/tools/ioemu/vl.c +++ b/tools/ioemu/vl.c @@ -523,8 +523,8 @@ int64_t cpu_get_real_ticks(void) #elif defined(__ia64__) #include "ia64_intrinsic.h" -#define cpu_get_reak_ticks() \ - ia64_getreg(_IA64_REG_AR_ITC) +#define cpu_get_real_ticks() \ + __ia64_getreg(_IA64_REG_AR_ITC) #else #error unsupported CPU diff --git a/tools/libxc/xc_ia64_stubs.c b/tools/libxc/xc_ia64_stubs.c index b21959b8d2..c246cbbdc6 100644 --- a/tools/libxc/xc_ia64_stubs.c +++ b/tools/libxc/xc_ia64_stubs.c @@ -603,6 +603,7 @@ int xc_vmx_build(int xc_handle, int memsize, const char *image_name, unsigned int control_evtchn, + unsigned int lapic, unsigned int vcpus, unsigned int store_evtchn, unsigned long *store_mfn) diff --git a/tools/libxc/xc_linux_build.c b/tools/libxc/xc_linux_build.c index de4a64f11a..49ed75e52d 100644 --- a/tools/libxc/xc_linux_build.c +++ b/tools/libxc/xc_linux_build.c @@ -783,7 +783,7 @@ int xc_linux_build(int xc_handle, /* currently done by hypervisor, should move here */ /* ctxt->regs.r28 = dom_fw_setup(); */ ctxt->vcpu.privregs = 0; - ctxt->sys_pgnr = nr_pages - 3; + ctxt->sys_pgnr = 3; i = 0; /* silence unused variable warning */ #else /* x86 */ /* diff --git a/xen/arch/ia64/Makefile b/xen/arch/ia64/Makefile index 3eabd0b7ed..08bc8aafe1 100644 --- a/xen/arch/ia64/Makefile +++ b/xen/arch/ia64/Makefile @@ -15,7 +15,7 @@ OBJS = xensetup.o setup.o time.o irq.o ia64_ksyms.o process.o smp.o \ OBJS += vmx_init.o vmx_virt.o vmx_vcpu.o vmx_process.o vmx_vsa.o vmx_ivt.o\ vmx_phy_mode.o vmx_utility.o vmx_interrupt.o vmx_entry.o vmmu.o \ vtlb.o mmio.o vlsapic.o vmx_hypercall.o mm.o vmx_support.o \ - pal_emul.o vmx_irq_ia64.o + pal_emul.o vmx_irq_ia64.o vmx_vioapic.o # lib files from xen/arch/ia64/linux/ (linux/arch/ia64/lib) OBJS += bitop.o clear_page.o flush.o copy_page_mck.o \ @@ -68,6 +68,11 @@ $(BASEDIR)/include/asm-ia64/.offsets.h.stamp: || ln -s $(BASEDIR)/include/xen $(BASEDIR)/include/linux [ -e $(BASEDIR)/include/asm-ia64/xen ] \ || ln -s $(BASEDIR)/include/asm-ia64/linux $(BASEDIR)/include/asm-ia64/xen +# Link to DM file in Xen for ia64/vti + [ -e $(BASEDIR)/include/asm-ia64/vmx_vioapic.h ] \ + || ln -s ../../include/asm-x86/vmx_vioapic.h $(BASEDIR)/include/asm-ia64/vmx_vioapic.h + [ -e $(BASEDIR)/arch/ia64/vmx/vmx_vioapic.c ] \ + || ln -s ../../../arch/x86/dm/vmx_vioapic.c $(BASEDIR)/arch/ia64/vmx/vmx_vioapic.c # Solve circular reference on asm-offsets.h [ -f $(BASEDIR)/include/asm-ia64/asm-offsets.h ] \ || echo "#define IA64_TASK_SIZE 0" > $(BASEDIR)/include/asm-ia64/asm-offsets.h diff --git a/xen/arch/ia64/Rules.mk b/xen/arch/ia64/Rules.mk index 8eb31cc674..279761d893 100644 --- a/xen/arch/ia64/Rules.mk +++ b/xen/arch/ia64/Rules.mk @@ -24,7 +24,7 @@ CFLAGS += -I$(BASEDIR)/include/asm-ia64 -I$(BASEDIR)/include/asm-ia64/linux \ -I$(BASEDIR)/include/asm-ia64/linux-null \ -I$(BASEDIR)/arch/ia64/linux -I$(BASEDIR)/arch/ia64/linux-xen CFLAGS += -Wno-pointer-arith -Wredundant-decls -CFLAGS += -DIA64 -DXEN -DLINUX_2_6 +CFLAGS += -DIA64 -DXEN -DLINUX_2_6 -DV_IOSAPIC_READY CFLAGS += -ffixed-r13 -mfixed-range=f12-f15,f32-f127 CFLAGS += -w -g ifeq ($(VALIDATE_VT),y) diff --git a/xen/arch/ia64/vmx/mmio.c b/xen/arch/ia64/vmx/mmio.c index f603fb7351..a64c16829c 100644 --- a/xen/arch/ia64/vmx/mmio.c +++ b/xen/arch/ia64/vmx/mmio.c @@ -202,11 +202,13 @@ static void legacy_io_access(VCPU *vcpu, u64 pa, u64 *val, size_t s, int dir) return; } +extern struct vmx_mmio_handler vioapic_mmio_handler; static void mmio_access(VCPU *vcpu, u64 src_pa, u64 *dest, size_t s, int ma, int dir) { struct virutal_platform_def *v_plat; //mmio_type_t iot; unsigned long iot; + struct vmx_mmio_handler *vioapic_handler = &vioapic_mmio_handler; iot=__gpfn_is_io(vcpu->domain, src_pa>>PAGE_SHIFT); v_plat = vmx_vcpu_get_plat(vcpu); @@ -220,6 +222,11 @@ static void mmio_access(VCPU *vcpu, u64 src_pa, u64 *dest, size_t s, int ma, int case GPFN_GFW: break; case GPFN_IOSAPIC: + if (!dir) + vioapic_handler->write_handler(vcpu, src_pa, s, *dest); + else + *dest = vioapic_handler->read_handler(vcpu, src_pa, s); + break; case GPFN_FRAME_BUFFER: case GPFN_LOW_MMIO: low_mmio_access(vcpu, src_pa, dest, s, dir); diff --git a/xen/arch/ia64/vmx/vlsapic.c b/xen/arch/ia64/vmx/vlsapic.c index 4034fbe457..340bdd40c4 100644 --- a/xen/arch/ia64/vmx/vlsapic.c +++ b/xen/arch/ia64/vmx/vlsapic.c @@ -37,15 +37,9 @@ #include #include #include +#include +#include -#define SHARED_VLAPIC_INF -#ifdef V_IOSAPIC_READY -static inline vl_apic_info* get_psapic(VCPU *vcpu) -{ - shared_iopage_t *sp = get_sp(vcpu->domain); - return &(sp->vcpu_iodata[vcpu->vcpu_id].apic_intr); -} -#endif //u64 fire_itc; //u64 fire_itc2; //u64 fire_itm; @@ -273,48 +267,71 @@ static void update_vhpi(VCPU *vcpu, int vec) } #ifdef V_IOSAPIC_READY -void vlapic_update_shared_info(VCPU *vcpu) -{ - //int i; - - vl_apic_info *ps; - - if (vcpu->domain == dom0) - return; - - ps = get_psapic(vcpu); - ps->vl_lapic_id = ((VCPU(vcpu, lid) >> 16) & 0xffff) << 16; - printf("vl_lapic_id = %x\n", ps->vl_lapic_id); - ps->vl_apr = 0; - // skip ps->vl_logical_dest && ps->vl_dest_format - // IPF support physical destination mode only - ps->vl_arb_id = 0; - /* - for ( i=0; i<4; i++ ) { - ps->tmr[i] = 0; // edge trigger +/* Assist to check virtual interrupt lines */ +void vmx_virq_line_assist(struct vcpu *v) +{ + global_iodata_t *spg = &get_sp(v->domain)->sp_global; + uint16_t *virq_line, irqs; + + virq_line = &spg->pic_irr; + if (*virq_line) { + do { + irqs = *(volatile uint16_t*)virq_line; + } while ((uint16_t)cmpxchg(virq_line, irqs, 0) != irqs); + vmx_vioapic_do_irqs(v->domain, irqs); } - */ + + virq_line = &spg->pic_clear_irr; + if (*virq_line) { + do { + irqs = *(volatile uint16_t*)virq_line; + } while ((uint16_t)cmpxchg(virq_line, irqs, 0) != irqs); + vmx_vioapic_do_irqs_clear(v->domain, irqs); + } +} + +void vmx_virq_line_init(struct domain *d) +{ + global_iodata_t *spg = &get_sp(d)->sp_global; + + spg->pic_elcr = 0xdef8; /* Level/Edge trigger mode */ + spg->pic_irr = 0; + spg->pic_last_irr = 0; + spg->pic_clear_irr = 0; } -void vlapic_update_ext_irq(VCPU *vcpu) +int ioapic_match_logical_addr(vmx_vioapic_t *s, int number, uint16_t dest) { - int vec; + return (VLAPIC_ID(s->lapic_info[number]) == dest); +} + +struct vlapic* apic_round_robin(struct domain *d, + uint8_t dest_mode, + uint8_t vector, + uint32_t bitmap) +{ + uint8_t bit; + vmx_vioapic_t *s; - vl_apic_info *ps = get_psapic(vcpu); - while ( (vec = highest_bits(ps->irr)) != NULL_VECTOR ) { - clear_bit (vec, ps->irr); - vmx_vcpu_pend_interrupt(vcpu, vec); + if (!bitmap) { + printk(" no bit on bitmap\n"); + return NULL; } + + s = &d->arch.vmx_platform.vmx_vioapic; + for (bit = 0; bit < s->lapic_count; bit++) { + if (bitmap & (1 << bit)) + return s->lapic_info[bit]; + } + + return NULL; } #endif void vlsapic_reset(VCPU *vcpu) { int i; -#ifdef V_IOSAPIC_READY - vl_apic_info *psapic; // shared lapic inf. -#endif - + VCPU(vcpu, lid) = ia64_getreg(_IA64_REG_CR_LID); VCPU(vcpu, ivr) = 0; VCPU(vcpu,tpr) = 0x10000; @@ -331,9 +348,10 @@ void vlsapic_reset(VCPU *vcpu) for ( i=0; i<4; i++) { VLSAPIC_INSVC(vcpu,i) = 0; } + #ifdef V_IOSAPIC_READY - vlapic_update_shared_info(vcpu); - //vlapic_update_shared_irr(vcpu); + vcpu->arch.arch_vmx.vlapic.vcpu = vcpu; + vmx_vioapic_add_lapic(&vcpu->arch.arch_vmx.vlapic, vcpu); #endif DPRINTK("VLSAPIC inservice base=%lp\n", &VLSAPIC_INSVC(vcpu,0) ); } diff --git a/xen/arch/ia64/vmx/vmx_init.c b/xen/arch/ia64/vmx/vmx_init.c index 452a96e093..3334b0c77d 100644 --- a/xen/arch/ia64/vmx/vmx_init.c +++ b/xen/arch/ia64/vmx/vmx_init.c @@ -48,9 +48,11 @@ #include #include #include +#include /* Global flag to identify whether Intel vmx feature is on */ u32 vmx_enabled = 0; +unsigned int opt_vmx_debug_level = 0; static u32 vm_order; static u64 buffer_size; static u64 vp_env_info; @@ -307,9 +309,8 @@ vmx_change_double_mapping(struct vcpu *v, u64 oldrr7, u64 newrr7) * is registered here. */ void -vmx_final_setup_domain(struct domain *d) +vmx_final_setup_guest(struct vcpu *v) { - struct vcpu *v = d->vcpu[0]; vpd_t *vpd; /* Allocate resources for vcpu 0 */ @@ -318,8 +319,7 @@ vmx_final_setup_domain(struct domain *d) vpd = alloc_vpd(); ASSERT(vpd); -// v->arch.arch_vmx.vpd = vpd; - v->arch.privregs = vpd; + v->arch.privregs = vpd; vpd->virt_env_vaddr = vm_buffer; /* Per-domain vTLB and vhpt implementation. Now vmx domain will stick @@ -341,7 +341,8 @@ vmx_final_setup_domain(struct domain *d) vlsapic_reset(v); vtm_init(v); - /* Other vmx specific initialization work */ + /* One more step to enable interrupt assist */ + set_bit(ARCH_VMX_INTR_ASSIST, &v->arch.arch_vmx.flags); } typedef struct io_range { @@ -431,9 +432,8 @@ int vmx_alloc_contig_pages(struct domain *d) return 0; } -void vmx_setup_platform(struct vcpu *v, struct vcpu_guest_context *c) +void vmx_setup_platform(struct domain *d, struct vcpu_guest_context *c) { - struct domain *d = v->domain; shared_iopage_t *sp; ASSERT(d != dom0); /* only for non-privileged vti domain */ @@ -441,27 +441,19 @@ void vmx_setup_platform(struct vcpu *v, struct vcpu_guest_context *c) __va(__gpa_to_mpa(d, IO_PAGE_START)); sp = get_sp(d); //memset((char *)sp,0,PAGE_SIZE); - //sp->sp_global.eport = 2; -#ifdef V_IOSAPIC_READY - sp->vcpu_number = 1; -#endif /* TEMP */ d->arch.vmx_platform.pib_base = 0xfee00000UL; - /* One more step to enable interrupt assist */ - set_bit(ARCH_VMX_INTR_ASSIST, &v->arch.arch_vmx.flags); /* Only open one port for I/O and interrupt emulation */ - if (v == d->vcpu[0]) { - memset(&d->shared_info->evtchn_mask[0], 0xff, - sizeof(d->shared_info->evtchn_mask)); - clear_bit(iopacket_port(d), &d->shared_info->evtchn_mask[0]); - } - - /* FIXME: only support PMT table continuously by far */ -// d->arch.pmt = __va(c->pt_base); + memset(&d->shared_info->evtchn_mask[0], 0xff, + sizeof(d->shared_info->evtchn_mask)); + clear_bit(iopacket_port(d), &d->shared_info->evtchn_mask[0]); + /* Initialize the virtual interrupt lines */ + vmx_virq_line_init(d); - vmx_final_setup_domain(d); + /* Initialize iosapic model within hypervisor */ + vmx_vioapic_init(d); } diff --git a/xen/arch/ia64/vmx/vmx_support.c b/xen/arch/ia64/vmx/vmx_support.c index 25f3db74ec..19ea7be6de 100644 --- a/xen/arch/ia64/vmx/vmx_support.c +++ b/xen/arch/ia64/vmx/vmx_support.c @@ -156,9 +156,8 @@ void vmx_intr_assist(struct vcpu *v) panic("Corruption: bad shared page: %lx\n", (unsigned long)vio); #ifdef V_IOSAPIC_READY - vlapic_update_ext_irq(v); -#else - //panic("IOSAPIC model is missed in qemu\n"); + /* Confirm virtual interrupt line signals, and set pending bits in vpd */ + vmx_virq_line_assist(v); #endif return; } diff --git a/xen/arch/ia64/xen/domain.c b/xen/arch/ia64/xen/domain.c index 8cf6c86cde..15920ca8a0 100644 --- a/xen/arch/ia64/xen/domain.c +++ b/xen/arch/ia64/xen/domain.c @@ -293,10 +293,14 @@ int arch_set_info_guest(struct vcpu *v, struct vcpu_guest_context *c) return -EINVAL; } - vmx_setup_platform(v, c); + if (v == d->vcpu[0]) + vmx_setup_platform(d, c); + + vmx_final_setup_guest(v); } *regs = c->regs; + d->arch.sys_pgnr = c->sys_pgnr; new_thread(v, regs->cr_iip, 0, 0); v->vcpu_info->arch.evtchn_vector = c->vcpu.evtchn_vector; @@ -307,7 +311,6 @@ int arch_set_info_guest(struct vcpu *v, struct vcpu_guest_context *c) } v->arch.domain_itm_last = -1L; - d->arch.sys_pgnr = c->sys_pgnr; d->shared_info->arch = c->shared; /* Don't redo final setup */ @@ -991,7 +994,7 @@ int construct_dom0(struct domain *d, */ printk("Dom0: 0x%lx, domain: 0x%lx\n", (u64)dom0, (u64)d); if (vmx_dom0) - vmx_final_setup_domain(dom0); + vmx_final_setup_guest(v); set_bit(_VCPUF_initialised, &v->vcpu_flags); diff --git a/xen/arch/x86/dm/vmx_vioapic.c b/xen/arch/x86/dm/vmx_vioapic.c index b36a1b7bc8..8f74f74eb4 100644 --- a/xen/arch/x86/dm/vmx_vioapic.c +++ b/xen/arch/x86/dm/vmx_vioapic.c @@ -297,12 +297,14 @@ static int ioapic_inj_irq(vmx_vioapic_t *s, switch (delivery_mode) { case VLAPIC_DELIV_MODE_FIXED: case VLAPIC_DELIV_MODE_LPRI: - if (test_and_set_bit(vector, &target->irr[0]) && trig_mode == 1) { + if (test_and_set_bit(vector, &VLAPIC_IRR(target)) && trig_mode == 1) { /* the level interrupt should not happen before it is cleard */ printk(" level interrupt happen before cleard\n"); } +#ifndef __ia64__ if (trig_mode) test_and_set_bit(vector, &target->tmr[0]); +#endif result = 1; break; default: @@ -367,7 +369,7 @@ static uint32_t ioapic_get_delivery_bitmask(vmx_vioapic_t *s, if (dest_mode == 0) { /* Physical mode */ for (i = 0; i < s->lapic_count; i++) { - if (s->lapic_info[i]->id == dest) { + if (VLAPIC_ID(s->lapic_info[i]) == dest) { mask = 1 << i; break; } diff --git a/xen/include/asm-ia64/vmx.h b/xen/include/asm-ia64/vmx.h index cdded3dfd2..8e21eec0d9 100644 --- a/xen/include/asm-ia64/vmx.h +++ b/xen/include/asm-ia64/vmx.h @@ -25,14 +25,13 @@ #define RR7_SWITCH_SHIFT 12 /* 4k enough */ #include - extern void identify_vmx_feature(void); extern unsigned int vmx_enabled; extern void vmx_init_env(void); -extern void vmx_final_setup_domain(struct domain *d); +extern void vmx_final_setup_guest(struct vcpu *v); extern void vmx_save_state(struct vcpu *v); extern void vmx_load_state(struct vcpu *v); -extern void vmx_setup_platform(struct vcpu *v, struct vcpu_guest_context *c); +extern void vmx_setup_platform(struct domain *d, struct vcpu_guest_context *c); #ifdef XEN_DBL_MAPPING extern vmx_insert_double_mapping(u64,u64,u64,u64,u64); extern void vmx_purge_double_mapping(u64, u64, u64); @@ -57,4 +56,22 @@ static inline shared_iopage_t *get_sp(struct domain *d) { return (shared_iopage_t *)d->arch.vmx_platform.shared_page_va; } + +typedef unsigned long (*vmx_mmio_read_t)(struct vcpu *v, + unsigned long addr, + unsigned long length); + +typedef void (*vmx_mmio_write_t)(struct vcpu *v, + unsigned long addr, + unsigned long length, + unsigned long val); + +typedef int (*vmx_mmio_check_t)(struct vcpu *v, unsigned long addr); + +struct vmx_mmio_handler { + vmx_mmio_check_t check_handler; + vmx_mmio_read_t read_handler; + vmx_mmio_write_t write_handler; +}; + #endif /* _ASM_IA64_VT_H */ diff --git a/xen/include/asm-ia64/vmx_platform.h b/xen/include/asm-ia64/vmx_platform.h index 37560863fa..e36188898a 100644 --- a/xen/include/asm-ia64/vmx_platform.h +++ b/xen/include/asm-ia64/vmx_platform.h @@ -20,18 +20,54 @@ #define __ASM_IA64_VMX_PLATFORM_H__ #include - +#include +#include struct mmio_list; typedef struct virutal_platform_def { - //unsigned long *real_mode_data; /* E820, etc. */ - unsigned long shared_page_va; - //struct vmx_virpit_t vmx_pit; - //struct vmx_handler_t vmx_handler; - //struct mi_per_cpu_info mpci; /* MMIO */ + unsigned long shared_page_va; unsigned long pib_base; unsigned char xtp; struct mmio_list *mmio; + /* One IOSAPIC now... */ + struct vmx_vioapic vmx_vioapic; } vir_plat_t; +static inline int __fls(uint32_t word) +{ + long double d = word; + long exp; + + __asm__ __volatile__ ("getf.exp %0=%1" : "=r"(exp) : "f"(d)); + return word ? (exp - 0xffff) : -1; +} + +/* This is a connect structure between vIOSAPIC model and vLSAPIC model. + * vlapic is required by vIOSAPIC model to manipulate pending bits, and + * we just map them into vpd here + */ +typedef struct vlapic { + struct vcpu *vcpu; /* Link to current vcpu */ +} vlapic_t; + +extern uint64_t dummy_tmr[]; +#define VCPU(_v,_x) _v->arch.privregs->_x +#define VLAPIC_ID(l) (uint16_t)(VCPU((l)->vcpu, lid) >> 16) +#define VLAPIC_IRR(l) VCPU((l)->vcpu, irr[0]) + +/* As long as we register vlsapic to ioapic controller, it's said enabled */ +#define vlapic_enabled(l) 1 +#define vmx_apic_support(d) 1 + +#define VLAPIC_DELIV_MODE_FIXED 0x0 +#define VLAPIC_DELIV_MODE_REDIR 0x1 +#define VLAPIC_DELIV_MODE_LPRI VLAPIC_DELIV_MODE_REDIR +#define VLAPIC_DELIV_MODE_PMI 0x2 +#define VLAPIC_DELIV_MODE_SMI 0x2 /* For IA32 */ +#define VLAPIC_DELIV_MODE_RESERVED 0x3 +#define VLAPIC_DELIV_MODE_NMI 0x4 +#define VLAPIC_DELIV_MODE_INIT 0x5 +#define VLAPIC_DELIV_MODE_STARTUP 0x6 /* For IA32 */ +#define VLAPIC_DELIV_MODE_EXT 0x7 + #endif diff --git a/xen/include/asm-ia64/vmx_vcpu.h b/xen/include/asm-ia64/vmx_vcpu.h index f0729b3e0a..509e3732a6 100644 --- a/xen/include/asm-ia64/vmx_vcpu.h +++ b/xen/include/asm-ia64/vmx_vcpu.h @@ -107,10 +107,6 @@ extern void vtm_set_itv(VCPU *vcpu); extern void vtm_interruption_update(VCPU *vcpu, vtime_t* vtm); extern void vtm_domain_out(VCPU *vcpu); extern void vtm_domain_in(VCPU *vcpu); -#ifdef V_IOSAPIC_READY -extern void vlapic_update_ext_irq(VCPU *vcpu); -extern void vlapic_update_shared_info(VCPU *vcpu); -#endif extern void vlsapic_reset(VCPU *vcpu); extern int vmx_check_pending_irq(VCPU *vcpu); extern void guest_write_eoi(VCPU *vcpu); @@ -278,9 +274,6 @@ IA64FAULT vmx_vcpu_set_lid(VCPU *vcpu, u64 val) { VCPU(vcpu,lid)=val; -#ifdef V_IOSAPIC_READY - vlapic_update_shared_info(vcpu); -#endif return IA64_NO_FAULT; } extern IA64FAULT vmx_vcpu_set_tpr(VCPU *vcpu, u64 val); diff --git a/xen/include/asm-ia64/vmx_vpd.h b/xen/include/asm-ia64/vmx_vpd.h index 04fd57c151..4f0e74aaae 100644 --- a/xen/include/asm-ia64/vmx_vpd.h +++ b/xen/include/asm-ia64/vmx_vpd.h @@ -25,6 +25,7 @@ #ifndef __ASSEMBLY__ #include +#include #include #define VPD_SHIFT 17 /* 128K requirement */ @@ -65,7 +66,8 @@ typedef struct { struct arch_vmx_struct { // struct virutal_platform_def vmx_platform; // vpd_t *vpd; - vtime_t vtm; + vtime_t vtm; + struct vlapic vlapic; unsigned long vrr[8]; unsigned long vkr[8]; unsigned long cr_iipa; /* for emulation */ @@ -106,6 +108,7 @@ struct arch_vmx_struct { #define DBG_LEVEL_3 (1 << 3) #define DBG_LEVEL_IO (1 << 4) #define DBG_LEVEL_VMMU (1 << 5) +#define DBG_LEVEL_IOAPIC (1 << 6) extern unsigned int opt_vmx_debug_level; #define VMX_DBG_LOG(level, _f, _a...) \ diff --git a/xen/include/asm-x86/vmx_vioapic.h b/xen/include/asm-x86/vmx_vioapic.h index 9f0f5bd897..98fc0bf30a 100644 --- a/xen/include/asm-x86/vmx_vioapic.h +++ b/xen/include/asm-x86/vmx_vioapic.h @@ -63,25 +63,6 @@ #define IOAPIC_REG_VERSION 0x1 -#ifdef __ia64__ -typedef union RedirStatus -{ - uint64_t value; - struct { - uint16_t dest_id; - uint8_t reserved[3]; - uint8_t reserve:7; - uint8_t mask:1; /* interrupt mask*/ - uint8_t trigmod:1; - uint8_t remoteirr:1; - uint8_t polarity:1; - uint8_t delivestatus:1; - uint8_t destmode:1; - uint8_t deliver_mode:3; - uint8_t vector; - } RedirForm; -} RedirStatus; -#else typedef union RedirStatus { uint64_t value; @@ -95,11 +76,15 @@ typedef union RedirStatus uint8_t trigmod:1; uint8_t mask:1; /* interrupt mask*/ uint8_t reserve:7; +#ifndef __ia64__ uint8_t reserved[4]; uint8_t dest_id; +#else + uint8_t reserved[3]; + uint16_t dest_id; +#endif } RedirForm; } RedirStatus; -#endif #define IOAPIC_MEM_LENGTH 0x100 #define IOAPIC_ENABLE_MASK 0x0 diff --git a/xen/include/asm-x86/vmx_vlapic.h b/xen/include/asm-x86/vmx_vlapic.h index 24a09e0096..991a6f36c1 100644 --- a/xen/include/asm-x86/vmx_vlapic.h +++ b/xen/include/asm-x86/vmx_vlapic.h @@ -151,6 +151,9 @@ static __inline__ int find_highest_bit(uint32_t *data, int length) #define vlapic_global_enabled(vlapic) \ !(test_bit(_VLAPIC_GLOB_DISABLE, &(vlapic)->status)) +#define VLAPIC_IRR(t) ((t)->irr[0]) +#define VLAPIC_ID(t) ((t)->id) + typedef struct direct_intr_info { int deliver_mode; int source[6]; -- 2.30.2